package com.bwie.service.impl;

import com.bwie.config.OSSFileUtil;
import com.bwie.mapper.EventsMapper;
import com.bwie.pojo.TbEvents;
import com.bwie.service.EventsService;
import com.bwie.utils.R;
import com.bwie.vo.EsEvents;
import com.bwie.vo.PageVo;
import com.mysql.jdbc.StringUtils;
import com.sun.corba.se.impl.oa.toa.TOA;
import org.eclipse.jetty.util.StringUtil;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

/**
 * @Title:
 * @BelongProjecet zk2
 * @BelongPackage com.bwie.service.impl
 * @Description:
 * @Copyright 研发一部
 * @Author: Mr.yan
 * @Date: 2024/6/3 9:21
 * @Version V1.0
 */
@Service
public class EventsServiceImpl implements EventsService {

    @Autowired
    private EventsMapper eventsMapper;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Autowired
    private OSSFileUtil ossFileUtil;

    @Override
    public R createIndex() {
        //1.创建索引
        IndexOperations indexOps = elasticsearchRestTemplate.indexOps(EsEvents.class);
        if (indexOps.exists()){
            return R.error(500,"已存在不能重复创建");
        }
        indexOps.create();

        //2.创建映射
        Document mapping = indexOps.createMapping();
        indexOps.putMapping(mapping);

        return R.success();
    }

    @Override
    public R eventsList(PageVo pageVo) {
        //1.分页
        Integer pageNum = 0;
        if (pageVo.getPageNum()>0){
            pageNum = pageVo.getPageNum()-1;
        }
        PageRequest pageRequest = PageRequest.of(pageNum, pageVo.getPageSize());

        //2.设置高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<font color='red'>").postTags("</font>")
                .field(new HighlightBuilder.Field("eventsName"));

        //3.模糊查询
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if (!StringUtil.isEmpty(pageVo.getName())) {
            boolQueryBuilder.must(
                    QueryBuilders.matchQuery("eventsName", pageVo.getName())
            );
        }

        //4.获取数据
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withPageable(pageRequest)
                .withHighlightBuilder(highlightBuilder)
                .withQuery(boolQueryBuilder);

        SearchHits<EsEvents> search = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), EsEvents.class);
        //5.获取总数据
        long total = search.getTotalHits();
        System.out.println("总共获取"+total+"条数据");

        //6.获取对象
        ArrayList<EsEvents> records = new ArrayList<>();

        for (SearchHit<EsEvents> hit : search) {
            EsEvents esEvents = hit.getContent();
            List<String> eventsName = hit.getHighlightField("eventsName");
            if (eventsName!=null && eventsName.size()>0){
                esEvents.setEventsName(eventsName.get(0));
            }
            records.add(esEvents);
        }

        HashMap<String, Object> map = new HashMap<>();
        map.put("total", total);
        map.put("pageNum", pageNum);
        map.put("pageSize", pageVo.getPageSize());
        map.put("records", records);

        return R.success(map);
    }

    @Override
    public R addEvents(EsEvents esEvents) {
        //1.先添加数据库
        TbEvents tbEvents = new TbEvents();
        BeanUtils.copyProperties(esEvents,tbEvents);

        eventsMapper.insert(tbEvents);

        //2.更新缓存
        esEvents.setId(tbEvents.getId());
        elasticsearchRestTemplate.save(esEvents);
        return R.success();
    }

    @Override
    public R uploadFile(MultipartFile file) {
        //调用上传图片的方法
        try {
            String url = ossFileUtil.uploadFile(file);
            return R.success(url);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public R uploadVideo(MultipartFile file) {
        //为了防止视频过大，使用断点上传
        String url = null;
        try {
            url = ossFileUtil.uploadFileByBreakingPoint(file);
            return R.success(url);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    @Scheduled(cron = "0 0/5 * * * ?")
    public void updateData(){
        //1.通过数据库插叙数据
        List<EsEvents> esEventsList = eventsMapper.updateData();
        //2.同步数据
        elasticsearchRestTemplate.save(esEventsList);
    }
}
